var defaultFactoryOptions = {
    background: {
        imageOptions: null,
        width: 0,
        height: 0
    },
    tanks: {
        lightTank: {
            imageOptions: null,
            width: 0,
            height: 0
        },
        mediumTank: {
            imageOptions: null,
            width: 0,
            height: 0
        },
        heavyTank: {
            imageOptions: null,
            width: 0,
            height: 0
        }
    },
    rockets: {
        simple: {
            imageOptions: null,
            width: 0,
            height: 0
        }
    },
    staticObjects: {
        wall: {
            imageOptions: null,
            width: 0,
            height: 0
        },
        forest: {
            imageOptions: null,
            width: 0,
            height: 0
        },
        water: {
            imageOptions: null,
            width: 0,
            height: 0
        }
    }
},
SimpleObjectsFactory = function (factoryOptions) {
    TankBase.prototype.rocketOptions = factoryOptions.rockets.simple;
    TankBase.prototype.move = epam.tankBattles.strategies.simpleTank.move;
    TankBase.prototype.cannotMove = epam.tankBattles.strategies.simpleTank.cannotMove;

    Rocket.prototype.move = epam.tankBattles.strategies.simpleRocket.move;
    Rocket.prototype.destroy = epam.tankBattles.strategies.simpleRocket.destroy;

    this.destroyRocket = function (rocket, startAnimation, stopAnimation) {
        var animation = new WhenRocketDestroyed(rocket.x, rocket.y, rocket.width, rocket.height, rocket.direction, factoryOptions.rockets.simple.animationOptions);
        startAnimation(animation);
        animation.stopAnimation = stopAnimation;
    };
    this.createBackground = function () {
        return new Background(factoryOptions.background.width, factoryOptions.background.height, factoryOptions.background.imageOptions);
    };
    this.createBackground = function () {
        return new Background(factoryOptions.background.width, factoryOptions.background.height, factoryOptions.background.imageOptions);
    };
    this.createPlayer = function () {
        var player = new LightTank(
            factoryOptions.background.width / 2 - factoryOptions.player.width / 2,
            factoryOptions.background.height - factoryOptions.player.height,
            factoryOptions.player.width,
            factoryOptions.player.height,
            epam.tankBattles.enum.direction.up,
            factoryOptions.player.imageOptions);

        player.move = epam.tankBattles.player.move;

        return AddHealthIndicator(AddWeaponTimeoutIndicator(AddFrameAround(player)));
    };
    this.createEnemies = function () {
        var tanks = [
            new LightTank(
                0,
                factoryOptions.background.height - factoryOptions.tanks.lightTank.height,
                factoryOptions.tanks.lightTank.width,
                factoryOptions.tanks.lightTank.height,
                epam.tankBattles.enum.direction.up,
                factoryOptions.tanks.lightTank.imageOptions),

            new LightTank(
                factoryOptions.background.width - factoryOptions.tanks.lightTank.width,
                factoryOptions.background.height - factoryOptions.tanks.lightTank.height,
                factoryOptions.tanks.lightTank.width,
                factoryOptions.tanks.lightTank.height,
                epam.tankBattles.enum.direction.up,
                factoryOptions.tanks.lightTank.imageOptions),

            new HeavyTank(
                factoryOptions.background.width / 2 - factoryOptions.tanks.heavyTank.width / 2,
                0,
                factoryOptions.tanks.heavyTank.width,
                factoryOptions.tanks.heavyTank.height,
                epam.tankBattles.enum.direction.down,
                factoryOptions.tanks.heavyTank.imageOptions),

            new MediumTank(
                0,
                0,
                factoryOptions.tanks.mediumTank.width,
                factoryOptions.tanks.mediumTank.height,
                epam.tankBattles.enum.direction.down,
                factoryOptions.tanks.mediumTank.imageOptions),

            new MediumTank(
                factoryOptions.background.width - factoryOptions.tanks.mediumTank.width,
                0,
                factoryOptions.tanks.mediumTank.width,
                factoryOptions.tanks.mediumTank.height,
                epam.tankBattles.enum.direction.down,
                factoryOptions.tanks.mediumTank.imageOptions)
        ];

        for (var i = 0, len = tanks.length; i < len; i++) {
            tanks[i] = AddHealthIndicator(AddWeaponTimeoutIndicator(tanks[i]));
        }

        return tanks;
    };
    this.createMapObjects = function () {
        var staticObjs = [];
        var cx = factoryOptions.background.width / 2 - factoryOptions.staticObjects.wall.width,
            cy = factoryOptions.background.height / 2 - factoryOptions.staticObjects.wall.height;

        var drawWalls = function (wallRows) {
            for (var i = 0; i < wallRows; i++) {
                staticObjs.push(new Wall(
                    cx + (wallRows - i) * factoryOptions.staticObjects.wall.width,
                    cy - (i + 1) * factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.width,
                    factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.imageOptions));

                staticObjs.push(new Wall(
                    cx - (wallRows - i) * factoryOptions.staticObjects.wall.width,
                    cy - (i + 1) * factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.width,
                    factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.imageOptions));

                staticObjs.push(new Wall(
                    cx + (wallRows - i) * factoryOptions.staticObjects.wall.width,
                    cy + (i + 1) * factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.width,
                    factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.imageOptions));

                staticObjs.push(new Wall(
                    cx - (wallRows - i) * factoryOptions.staticObjects.wall.width,
                    cy + (i + 1) * factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.width,
                    factoryOptions.staticObjects.wall.height,
                    factoryOptions.staticObjects.wall.imageOptions));
            }
        },
        drawForest = function (forestRows) {
            for (var i = 0; i < forestRows; i++) {
                staticObjs.push(new Forest(
                    cx + (forestRows - i) * factoryOptions.staticObjects.forest.width,
                    cy - (i + 1) * factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.width,
                    factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.imageOptions));

                staticObjs.push(new Forest(
                    cx - (forestRows - i) * factoryOptions.staticObjects.forest.width,
                    cy - (i + 1) * factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.width,
                    factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.imageOptions));

                staticObjs.push(new Forest(
                    cx + (forestRows - i) * factoryOptions.staticObjects.forest.width,
                    cy + (i + 1) * factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.width,
                    factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.imageOptions));

                staticObjs.push(new Forest(
                    cx - (forestRows - i) * factoryOptions.staticObjects.forest.width,
                    cy + (i + 1) * factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.width,
                    factoryOptions.staticObjects.forest.height,
                    factoryOptions.staticObjects.forest.imageOptions));
            }
        },
        drawWater = function (waterRows) {
            for (var i = 0; i < waterRows; i++) {
                staticObjs.push(new Water(
                    cx + (waterRows - i) * factoryOptions.staticObjects.water.width,
                    cy - (i + 1) * factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.width,
                    factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.imageOptions));

                staticObjs.push(new Water(
                    cx - (waterRows - i) * factoryOptions.staticObjects.water.width,
                    cy - (i + 1) * factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.width,
                    factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.imageOptions));

                staticObjs.push(new Water(
                    cx + (waterRows - i) * factoryOptions.staticObjects.water.width,
                    cy + (i + 1) * factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.width,
                    factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.imageOptions));

                staticObjs.push(new Water(
                    cx - (waterRows - i) * factoryOptions.staticObjects.water.width,
                    cy + (i + 1) * factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.width,
                    factoryOptions.staticObjects.water.height,
                    factoryOptions.staticObjects.water.imageOptions));
            }
        };

        drawWater(1);
        drawWater(2);
        drawWater(3);
        drawForest(4);
        drawForest(5);
        drawForest(6);
        drawForest(7);
        drawWalls(8);
        drawWalls(9);

        return staticObjs;
    };
    this.whenRocketDestroyed = function (rocket) {
        return new WhenRocketDestroyed(rocket.x, rocket.y, rocket.width, rocket.height, factoryOptions.rockets.simple.animation.imageOptions)
    }
};

epam.tankBattles.common.extend(SimpleObjectsFactory, GameObjectsFactory);
